package com.vogue.supplymall.order.domain.service.impl;

import com.vogue.ssm.database.dao.BaseDao;
import com.vogue.ssm.database.entity.SnowflakeIdWorker;
import com.vogue.ssm.database.util.DealStatus;
import com.vogue.supplymall.common.constant.ConstantBean;
import com.vogue.supplymall.order.domain.dao.OrderStatusDao;
import com.vogue.supplymall.order.domain.model.OrderStatus;
import com.vogue.supplymall.order.domain.service.OrderStatusService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * The type Order status service.
 *
 * @aouthor: zhangliang
 * @date: Create in 2018-02-06
 */
@Service("orderStatusService")
public class OrderStatusServiceImpl extends BaseServiceImpl<OrderStatus, Long> implements OrderStatusService {

    @Resource
    private OrderStatusDao orderStatusDao;

    /**
     * 查询所有待支付超时的订单
     */
    private static final String SELECT_ORDER_CANCEL_SQL = "SELECT o.tendid,o.id,o.syscodeid FROM order_status oss,`order` o "
            + "WHERE oss.orderid = o.id AND oss.orderstatus = 0 "
            + "AND NOT EXISTS (select 1 from order_cancel oc where oc.orderid = o.id) "
            + "AND TIMESTAMPDIFF(SECOND,o.modifydate,now()) >= "
            + (ConstantBean.PAY_FAILURE_TIME.longValue() / 1000L);

    /**
     * 更新所有假取消的订单为真取消
     */
    private static final String UPDATE_CANCEL_SQL =
            "UPDATE order_status oss,`order` o SET oss.iscancel = 1 "
                    + "WHERE oss.orderid = o.id "
                    + "AND oss.orderstatus = 0 AND oss.iscancel = 0 "
                    + "AND TIMESTAMPDIFF(SECOND,o.modifydate,now()) >= "
                    + (ConstantBean.PAY_FAILURE_TIME.longValue() / 1000L) + ";";

    /**
     * 查出支付方式包含预付货款的已经取消的订单并没有预付货款退款记录的单据，插入预付货款退款记录
     */
    private static final String SELECT_ADVANCE_PAYMENT_RETURN_SQL =
            "SELECT apd.tendid,apd.orderid,apd.accountid,apd.sellsyscodeid,apd.sellorganid,"
                    + "apd.sellmatchid,apd.buysyscodeid,apd.buyorganid,apd.buymatchid, "
                    + "apd.amount,apd.origin FROM order_status os , account_prepay_detail apd "
                    + "WHERE os.orderid = apd.orderid AND os.iscancel = 1 AND apd.`type`=1 "
                    + "AND NOT EXISTS (SELECT 1 FROM account_prepay_detail apd "
                    + "WHERE os.orderid = apd.orderid AND os.iscancel = 1 AND apd.`type`=3);";

    /**
     * 支付方式包含预付货款的订单未退款的订单把消费的预付货款金额加回对应的当前余额记录
     */
    private static final String ADD_ADVANCE_PAYMENT_RETURN_SQL =
            "UPDATE order_status os,account_prepay_detail apd,account_prepay ap SET ap.balance = ap.balance + apd.amount "
                    + "WHERE os.orderid = apd.orderid AND apd.tendid = ap.tendid AND apd.sellorganid=ap.sellorganid AND apd.buyorganid=ap.buyorganid "
                    + "AND os.iscancel = 1 AND apd.`type`=1 AND NOT EXISTS (SELECT 1 FROM account_prepay_detail apd "
                    + "WHERE os.orderid = apd.orderid AND os.iscancel = 1 AND apd.`type`=3);";

    /**
     * Instantiates a new Order status service.
     *
     * @param baseDao the base dao
     */
    public OrderStatusServiceImpl(BaseDao<OrderStatus, Long> baseDao) {
        super(baseDao);
    }

    @Override
    public Optional<OrderStatus> getByOrderId(Long orderId) {
        List<OrderStatus> orderStatus = orderStatusDao.getByOrderId(orderId);
        if (null != orderStatus) {
            return orderStatus.stream().findFirst();
        }
        return Optional.empty();
    }

    @Override
    @Transactional
    public void updateCancelState() {
        DealStatus.kacha();
        List<Map<String, Object>> list = orderStatusDao.query(SELECT_ORDER_CANCEL_SQL);
        StringBuilder str = new StringBuilder("INSERT INTO order_cancel (`id`, `tendid`, `orderid`, `syscodeid`, "
                + "`cancelstate`, `cancelcause`, `othercause`, `createdate`, `modifydate`) VALUES ");
        for (Map<String, Object> map : list) {
            str.append("(").append(SnowflakeIdWorker.getIns().nextId()).append(",")
                    .append(map.get("tendid")).append(",")
                    .append(map.get("id")).append(",")
                    .append(map.get("syscodeid")).append(",")
                    .append("0,6,'',now(),now())").append(",");
        }
        if (list != null && list.size() > 0) {
            String sql = str.substring(0, str.length() - 1) + ";";
            DealStatus.kacha();
            orderStatusDao.update(sql);
        }
        DealStatus.kacha();
        orderStatusDao.update(UPDATE_CANCEL_SQL);
        DealStatus.kacha();
        orderStatusDao.update(ADD_ADVANCE_PAYMENT_RETURN_SQL);
        list = orderStatusDao.query(SELECT_ADVANCE_PAYMENT_RETURN_SQL);
        str = new StringBuilder("INSERT INTO `account_prepay_detail` (`id`, `tendid`, `orderid`, `accountid`, "
                + "`sellsyscodeid`, `sellorganid`, `sellmatchid`, `buysyscodeid`, `buyorganid`, `buymatchid`, "
                + "`createdate`, `modifydate`, `amount`, `type`, `origin`, `memo`) VALUES ");
        for (Map<String, Object> map : list) {
            str.append("(").append(SnowflakeIdWorker.getIns().nextId()).append(",")
                    .append(map.get("tendid")).append(",")
                    .append(map.get("orderid")).append(",")
                    .append(map.get("accountid")).append(",")
                    .append(map.get("sellsyscodeid")).append(",")
                    .append(map.get("sellorganid")).append(",")
                    .append("'").append(map.get("sellmatchid")).append("'").append(",")
                    .append(map.get("buysyscodeid")).append(",")
                    .append(map.get("buyorganid")).append(",")
                    .append("'").append(map.get("buymatchid")).append("'").append(",")
                    .append("now()").append(",")
                    .append("now()").append(",")
                    .append(map.get("amount")).append(",")
                    .append(3).append(",")
                    .append(2).append(",")
                    .append("''").append(")").append(",");
        }
        if (list != null && list.size() > 0) {
            String sql = str.substring(0, str.length() - 1) + ";";
            DealStatus.kacha();
            orderStatusDao.update(sql);
        }
    }
}
